package com.guinea.core.acegi;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.dao.UserCache;
import org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache;
import org.acegisecurity.userdetails.UserDetails;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.guinea.system.entity.ResRoleRel;
import com.guinea.system.entity.Resource;
import com.guinea.system.entity.User;
import com.guinea.system.entity.UserRoleRel;
import com.guinea.system.service.ResourceService;
import com.guinea.system.service.UserService;

/**
 * cache管理
 * 
 * @author cac
 */
public class AcegiCacheManager {
	private static final Log logger = LogFactory
			.getLog(AcegiCacheManager.class);

	private ResourceCache resourceCache;

	private UserCache userCache;

	private boolean userCacheInitialized = false;

	private boolean resourceCacheInitialized = false;

	ResourceService resourceService;

	UserService userService;

	/**
	 * 修改User时更改userCache�
	 */
	public void modifyUserInCache(User user, String orgUsername) {
		UserDetails ud = userCache.getUserFromCache(orgUsername);
		if (ud != null)
			userCache.removeUserFromCache(orgUsername);
		userDetailsInCache(user);
	}

	/**
	 * 修改Resource时更改resourceCache
	 */
	public void modifyResourceInCache(Resource resource,
			String orgResourceString) {
		ResourceDetails resourceDetails = resourceCache
				.getAuthorityFromCache(orgResourceString);
		if (resourceDetails != null)
			resourceCache.removeAuthorityFromCache(orgResourceString);
		resourceDetailsInCache(resource);

	}

	/**
	 * 初始化userCache
	 */
	public void initUserCache() {
		if (!userCacheInitialized) {
			synchronized (this) {
				//超级管理员
				GrantedAuthority[] authorities = new GrantedAuthority[]{new GrantedAuthorityImpl("0")};
				UserDetails ud = new UserDetailsImpl(new Long(0), "admin",
						"admin", authorities);
				userCache.putUserInCache(ud);
				List users = userService.get();
				for (Iterator iter = users.iterator(); iter.hasNext();) {
					User user = (User) iter.next();
					userDetailsInCache(user);
				}
				userCacheInitialized = true;
			}
		}

	}

	public void refreshUserCache() {
		userCacheInitialized = false;
		try {
			((EhCacheBasedUserCache) userCache).getCache().removeAll();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		initUserCache();
	}

	public void refreshCaches() {
		refreshUserCache();
		refreshResourceCache();
	}

	/**
	 * 初始化resourceCache
	 */
	public void initResourceCache() {
		if (!resourceCacheInitialized) {
			synchronized (this) {
				List resources = resourceService.get();
				for (Iterator iter = resources.iterator(); iter.hasNext();) {
					Resource resource = (Resource) iter.next();
					resourceDetailsInCache(resource);
				}
				resourceCacheInitialized = true;
			}
		}
	}

	public void refreshResourceCache() {
		resourceCacheInitialized = false;
		try {
			resourceCache.getCache().removeAll();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		initResourceCache();
	}

	/**
	 * 获取所有资源
	 */
	public List getResStrings() {
		return resourceCache.getResources();
	}

	/**
	 * 根据资源串获取资源
	 */
	public ResourceDetails getAuthorityFromCache(String resString) {
		return resourceCache.getAuthorityFromCache(resString);
	}

	/**
	 * 获取user相应的权限并置于usercache中
	 */
	public void userDetailsInCache(User user) {
		GrantedAuthority[] authorities = userrole2authorities(user.getUserRoleRels());
		UserDetails ud = new UserDetailsImpl(user.getId(), user.getLoginName(),
				user.getLoginPassword(), authorities);
		userCache.putUserInCache(ud);
	}

	/**
	 * 获取resource相应的权限并置于resourcecache中
	 */
	public void resourceDetailsInCache(Resource resource) {
		GrantedAuthority[] authorities = resrole2authorities(resource.getResRoleRels());
		ResourceDetails resourceDetails = new ResourceDetails(resource
				.getResourceString(), resource.getId(), authorities);
		resourceCache.putAuthorityInCache(resourceDetails);
	}

	private GrantedAuthority[] userrole2authorities(Collection userRoleRels) {
		UserRoleRel userRoleRel;
		GrantedAuthority[] authorities = new GrantedAuthority[userRoleRels.size()];
		int i = 0;
		for (Iterator iter = userRoleRels.iterator(); iter.hasNext();) {
			userRoleRel = (UserRoleRel) iter.next();
			GrantedAuthority g = new GrantedAuthorityImpl(userRoleRel.getRole().getId()
					.longValue()
					+ "");
			authorities[i] = g;
			i++;
		}
		return authorities;
	}

	private GrantedAuthority[] resrole2authorities(Collection resRoleRels) {
		ResRoleRel resRoleRel;
		GrantedAuthority[] authorities = new GrantedAuthority[resRoleRels.size()];
		int i = 0;
		for (Iterator iter = resRoleRels.iterator(); iter.hasNext();) {
			resRoleRel = (ResRoleRel) iter.next();
			GrantedAuthority g = new GrantedAuthorityImpl(resRoleRel.getRole().getId()
					.longValue()
					+ "");
			authorities[i] = g;
			i++;
		}
		return authorities;
	}

	public void setResourceCache(ResourceCache resourceCache) {
		this.resourceCache = resourceCache;
	}

	public ResourceCache getResourceCache() {
		return resourceCache;
	}

	public UserCache getUserCache() {
		return userCache;
	}

	public void setUserCache(UserCache userCache) {
		this.userCache = userCache;
	}

	public ResourceService getResourceService() {
		return resourceService;
	}

	public void setResourceService(ResourceService resourceService) {
		this.resourceService = resourceService;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}


}
